﻿Imports System.Net
Imports ajayumi.develop.win32.GRssReader.Service.Model
Imports System.Collections.Generic
Imports System.IO
Imports System.ComponentModel


Public Class DownloadManager
    Inherits Collections.Generic.List(Of ArticleImageInfo)
    Implements IDisposable


#Region "Variables"
    Private ReadOnly m_LockObject As Object = Nothing
    Private m_WebClientList As List(Of WebClient) = Nothing
#End Region

#Region "Properties"

#End Region

#Region "Events"

    Public Event DownloadProgressChanged As ProgressChangedEventHandler
    Protected Overridable Sub OnDownloadProgressChanged(e As ProgressChangedEventArgs)
        RaiseEvent DownloadProgressChanged(Me, e)
    End Sub

#End Region

    Public Sub New()
        Me.m_LockObject = New Object()
        Me.m_WebClientList = New List(Of WebClient)()
    End Sub

    Public Sub [Start]()
        For Each _ArticleImageInfo As ArticleImageInfo In Me
            Dim _WebClient As New WebClient()
            AddHandler _WebClient.DownloadFileCompleted, AddressOf Me.WebClient_DownloadFileCompleted
            Me.m_WebClientList.Add(_WebClient)

            _WebClient.DownloadFileAsync(_ArticleImageInfo.Address, _ArticleImageInfo.LocalTempPath, _ArticleImageInfo)
        Next
    End Sub

    Private Sub WebClient_DownloadFileCompleted(sender As Object, e As System.ComponentModel.AsyncCompletedEventArgs)
        Dim _ArticleImageInfo As ArticleImageInfo = DirectCast(e.UserState, ArticleImageInfo)

        SyncLock Me.m_LockObject
            _ArticleImageInfo.IsDownloaded = True

            Dim _Count As Integer = (From o As ArticleImageInfo In Me _
                                     Where o.IsDownloaded = True _
                                     Select o).Count()

            Dim _Total As Integer = Me.Count()

            Console.WriteLine("{0}-{1}  {2}/{3}", _ArticleImageInfo.SubscriptionTitle, _ArticleImageInfo.ArticleTitle, _Count, _Total)

            Dim _ProgressPercentage As Integer = CInt((_Count / _Total) * 100.0!)
            Dim _Error As Exception = e.Error
            Try
                File.Copy(_ArticleImageInfo.LocalTempPath, _ArticleImageInfo.LocalPath, True)
                Me.m_WebClientList.Remove(DirectCast(sender, WebClient))
            Catch ex As Exception
                _Error = ex
            End Try

            Me.OnDownloadProgressChanged(New ProgressChangedEventArgs(_ProgressPercentage, Me))
        End SyncLock

    End Sub



#Region "IDisposable Support"
    Private disposedValue As Boolean ' 检测冗余的调用

    ' IDisposable
    Protected Overridable Sub Dispose(disposing As Boolean)
        If Not Me.disposedValue Then
            If disposing Then
                ' TODO: 释放托管状态(托管对象)。
                If Me.m_WebClientList IsNot Nothing Then
                    For Each Item As WebClient In Me.m_WebClientList
                        If Item.IsBusy Then
                            Item.CancelAsync()
                        End If
                        Item.Dispose()
                    Next
                    Me.m_WebClientList.Clear()
                    Me.m_WebClientList = Nothing
                End If
            End If

            ' TODO: 释放非托管资源(非托管对象)并重写下面的 Finalize()。
            ' TODO: 将大型字段设置为 null。
        End If
        Me.disposedValue = True
    End Sub

    ' TODO: 仅当上面的 Dispose(ByVal disposing As Boolean)具有释放非托管资源的代码时重写 Finalize()。
    'Protected Overrides Sub Finalize()
    '    ' 不要更改此代码。请将清理代码放入上面的 Dispose(ByVal disposing As Boolean)中。
    '    Dispose(False)
    '    MyBase.Finalize()
    'End Sub

    ' Visual Basic 添加此代码是为了正确实现可处置模式。
    Public Sub Dispose() Implements IDisposable.Dispose
        ' 不要更改此代码。请将清理代码放入上面的 Dispose(ByVal disposing As Boolean)中。
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub
#End Region

End Class
